---
title: "@unkey/hono"
description: "Hono.js middleware for authenticating API keys"
---

> Hono - [炎] means flame🔥 in Japanese - is a small, simple, and ultrafast web framework for the Edges. It works on any JavaScript runtime: Cloudflare Workers, Fastly Compute@Edge, Deno, Bun, Vercel, Netlify, Lagon, AWS Lambda, Lambda@Edge, and Node.js.

`@unkey/hono` offers a middleware for authenticating API keys with [unkey](https://unkey.com).

<Card
  icon="github"
  title="github.com/unkeyed/sdks/tree/main/hono"
  href="https://github.com/unkeyed/sdks/tree/main/hono"
/>

## Install

<CodeGroup>

```bash npm
 npm install @unkey/hono
```

```bash pnpm
 pnpm add @unkey/hono
```

```bash yarn
 yarn add @unkey/hono
```

```bash bun
 bun install @unkey/hono
```

</CodeGroup>

Let's dive straight in. The minimal setup looks like this. All you need is your root key with permission to verify keys. Go to [/settings/root-keys](https://app.unkey.com/settings/root-keys) and create a key with the `verify_key` permission.

By default it tries to grab the api key from the `Authorization` header and then verifies it with unkey.
The result of the verification will be written to the context and can be access with `c.get("unkey")`.

```ts
import { Hono } from "hono"
import { type UnkeyContext, unkey } from "@unkey/hono";

const app = new Hono<{ Variables: { unkey: UnkeyContext } }>();

app.use("*", unkey({
  rootKey: "<UNKEY_ROOT_KEY>"
}));


app.get("/somewhere", (c) => {
  // access the unkey response here to get metadata of the key etc
  const ... = c.get("unkey")

  return c.text("yo")
})
```

## Customizing the middleware

### Header

By default the middleware tries to grab the api key from the `Authorization` header. You can change this by passing a custom header name to the middleware.

```ts
app.use(
  "*",
  unkey({
    rootKey: "<UNKEY_ROOT_KEY>",
    getKey: (c) => c.req.header("x-api-key"),
  })
);
```

If the header is missing the middleware will return a `401` error response like this

```ts
c.json({ error: "unauthorized" }, { status: 401 });
```

To customize the response in case the header is missing, just return a response from the `getKey` function.

```ts
app.use(
  "*",
  unkey({
    rootKey: "<UNKEY_ROOT_KEY>",
    getKey: (c) => {
      const key = c.req.header("x-api-key");
      if (!key) {
        return c.text("missing api key", 401);
      }
      return key;
    },
  })
);
```

### Handle errors

```ts
app.use(
  "*",
  unkey({
    rootKey: process.env.UNKEY_ROOT_KEY!,
    onError: (c, err) => {
      // handle error
      return c.text("unauthorized", 401);
    },
  })
);
```

### Handle invalid keys

By default the middleware will not do anything with the verification response other than writing it to the context.
However you most likely would like to just return a `401` response if the key is invalid and not continue with the request.

To do this you can pass a `handleInvalidKey` handler to the middleware.
See [here](/api-reference/v2/keys/create-api-key) for the full `response` object.

```ts
app.use(
  "*",
  unkey({
    rootKey: process.env.UNKEY_ROOT_KEY!,
    handleInvalidKey: (c, result) => {
      return c.json(
        {
          error: "unauthorized",
          reason: result.data.code,
        },
        401
      );
    },
  })
);
```

### Pass verification tags

You can pass tags to the verification request to help you filter keys later.

```ts
(c, next) =>
  unkey({
    rootKey: process.env.UNKEY_ROOT_KEY!,
    tags: [`path=${c.req.path}`],
  })(c, next);
```
